package com.cyc.common.model;

import cn.hutool.core.util.ObjectUtil;
import com.cyc.common.enums.CodeEnum;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Data
@ApiModel("api接口通用返回对象")
@JsonInclude(JsonInclude.Include.NON_NULL)
@Slf4j
public class Result<T> {
	@ApiModelProperty(name = "returnStatus", value = "状态：SUCCEED 成功;FAILED 失败")
	private Result.Status returnStatus;
	@ApiModelProperty(name = "errorCode", value = "错误码")
	private String errorCode;
	@ApiModelProperty(name = "errorMessage", value = "错误信息")
	private String errorMessage;
	@ApiModelProperty(name = "extMessage", value = "扩展信息")
	private String extMessage;

	@ApiModelProperty(value = "结果主体")
	@JsonInclude(JsonInclude.Include.NON_NULL)
	private T data;

	public static <T> Result<T> success() {
		return resultData(Result.Status.SUCCEED, null, null, null);
	}

	public static <T> Result<T> success(T data) {
		return resultData(Result.Status.SUCCEED, null, null, data);
	}

	public static <T> Result<T> error() {
		return resultData(Result.Status.FAILED, null, null, null);
	}


	public static <T> Result<T> error(CodeEnum codeEnum) {
		return resultData(Result.Status.FAILED, codeEnum, null, null);
	}

	public static <T> Result<T> error(CodeEnum codeEnum,String extMessage) {
		return resultData(Result.Status.FAILED, codeEnum, extMessage, null);
	}

	public static <T> Result<T> error(CodeEnum codeEnum, String extMessage, T data) {
		return resultData(Result.Status.FAILED, codeEnum, extMessage, data);
	}

	private static <T> Result<T> resultData(Result.Status returnStatus, CodeEnum codeEnum, String extMessage, T data) {
		Result<T> resultData = new Result<T>();
		resultData.setReturnStatus(returnStatus);
		if(ObjectUtil.isNotNull(codeEnum)) {
			resultData.setErrorCode(codeEnum.getCode());
			resultData.setErrorMessage(codeEnum.getMsg());
		}
		resultData.setExtMessage(extMessage);
		resultData.setData(data);
		return resultData;
	}

	public static enum Status {
		SUCCEED, FAILED;
		private Status() {
		}
	}
}
